# -*- coding: utf-8 -*-
"""
Created on Mon May 15 09:07:06 2017

@author: GangTimes
"""
import numpy
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import dual
#绘图设置
zh_font=fm.FontProperties(fname=r"c:\windows\fonts\simsun.ttf",size=18)#路径用小写  大写不行 有这个不能保存为eps
en_font=fm.FontProperties(family='monospace',size=18)
zf_font=fm.FontProperties(family='Times New Roman',style='italic',size=16)

fig_model=plt.figure(figsize=(7,5))
ax_model=fig_model.add_axes([0.14,0.14,0.85,0.85])
plt.rcParams['axes.unicode_minus']=False #用来正常显示负


#全局参数
num=50
version = "0.1"

def self_plot(x,y,z):
    x1=[]
    x2=[]
    y1=[]
    y2=[]
    rows=x.shape[0]
    for index in range(rows):
        if z[index,0]==-1:
            x1.append(x[index,0])
            y1.append(y[index,0])
        else:
            x2.append(x[index,0])
            y2.append(y[index,0])
    
    ax_model.plot(x1,y1,"*r")
    ax_model.plot(x2,y2,"ok")

def model_plot(theta):
    '''
    绘制模型函数的图像
    theta: matrix[mx1]
    ax+by+c=0
    '''
    a=theta[0,0]
    b=theta[1,0]
    c=theta[2,0]
    
    x=numpy.linspace(0,1,100)
    y=(-a/b)*x+(-c/b)    
    ax_model.plot(x,y,'-r')
    plt.show()
 
 
def create_data(theta):
    '''
    用于生成一个二维空间的两种类型的点
    人为制造一定的误差
    return:matrix[nx3] n为样本数量  [x y z]三列
    '''
    x=numpy.matrix(numpy.random.uniform(0,1,num)).T
    y=numpy.matrix(numpy.random.uniform(0,1,num)).T  
    
    x_one=numpy.matrix(numpy.ones((num,1)))
    
    z=model_fun(theta,numpy.hstack((x,y,x_one)))
    self_plot(x,y,z)
    
    return numpy.hstack((x,y,z))    

	
def model_fun(theta,x):
    '''
    这是模型函数
    theta:系数 matrix[mx1]  m为变量数 
    b:系数 matrix[1x1]
    x:自变量 matrix[nxm]  n为样本数   m为变量数 包含x=1
    return: matrix[nx1]
    '''
    rows=x.shape[0]
    temp=(theta.T*x.T).T
    yval=[]
    if rows==1:
        yval.append(_sign_fun(temp[0,0],0))
        return numpy.matrix(yval)
    elif rows>1:
        for index in range(rows):
            yval.append(_sign_fun(temp[index,0],0))
        return numpy.matrix(yval).T
		
def _sign_fun(x,b):
    '''
    sign函数  符号判别函数
    x:自变量 
    b:参考变量
    '''
    if x>=b:
        return 1
    else:
        return -1

def residul_plot(loss):
    '''
    绘制残差曲线
    '''
    rs_fig=plt.figure(figsize=(7,5))
    ax=rs_fig.add_axes([0.14,0.14,0.85,0.85])
    ax.plot(loss,'-r')
    plt.show()

def dual_demo():
    rtheta=numpy.matrix([[1],[1],[-1]])
    temp=create_data(rtheta)
    x_one=numpy.matrix(numpy.ones((num,1)))
    x=numpy.hstack((temp[:,0:2],x_one))
    y=temp[:,2]
    
    [theta,loss]=dual.dual(x,y)
    
    model_plot(theta)
    residul_plot(loss)
    
    
if __name__=="__main__":
    dual_demo()
    
